package com.atguigu.dga230315.governance.utils;

import org.apache.hadoop.hive.ql.lib.DefaultGraphWalker;
import org.apache.hadoop.hive.ql.lib.Dispatcher;
import org.apache.hadoop.hive.ql.lib.GraphWalker;
import org.apache.hadoop.hive.ql.lib.Node;
import org.apache.hadoop.hive.ql.parse.ASTNode;
import org.apache.hadoop.hive.ql.parse.HiveParser;
import org.apache.hadoop.hive.ql.parse.ParseDriver;
import org.apache.hadoop.hive.ql.parse.SemanticException;

import java.util.Collections;
import java.util.Stack;

public class SqlParse {
    /**
     *
     * @param dispatcher  自定义节点处理器
     * @param sql    待分析的sql
     */
    public static void sqlParse(Dispatcher dispatcher, String sql )   {
        try {

            // 解析 Hive SQL
            ParseDriver parseDriver = new ParseDriver(); //创建解析引擎
            //执行解析  得到根节点
            ASTNode ast =  parseDriver.parse(sql);
            //  找到查询的根节点下的TOK_QUERY节点，视为有效根节点
            while (ast.getToken() == null || ast.getToken().getType() != HiveParser.TOK_QUERY) {
                ast = (ASTNode) ast.getChild(0);
            }

            // 把节点处理器注入一个图形遍历器   使用自定义处理器遍历抽象语法树
            GraphWalker ogw = new DefaultGraphWalker(dispatcher);
            // 用遍历器遍历整个语法树
            ogw.startWalking(Collections.singletonList(ast), null);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String sql = "select a,b,c from gmall.ordere where dt=1";
        sqlParse(new testDis(), sql);
    }


    public static class testDis implements  Dispatcher{

        /**
         *
         * @param nd  每次走到节点
         *          operator to process.
         * @param stack
         *          operator stack to process.
         * @param nodeOutputs
         *          The argument list of outputs from processing other nodes that are
         *          passed to this dispatcher from the walker.
         * @return
         * @throws SemanticException
         */
        @Override
        public Object dispatch(Node nd, Stack<Node> stack, Object... nodeOutputs) throws SemanticException {
            ASTNode astNode = (ASTNode) nd;
            System.out.println(astNode.getType()+"----"+astNode.getText());
            return null;
        }
    }

}
